package main

import (
	"fmt"
)

func printSlice(slice []int) {
	fmt.Printf("slice len: %d, cap: %d, value: %v\n", len(slice), cap(slice), slice)
	fmt.Println()
}

func testSlice1() {
	var slice1 []int = []int{1, 2, 3}
	printSlice(slice1)
	var slice2 []int = make([]int, 3, 5)
	slice2[0] = 4
	slice2[1] = 5
	slice2[2] = 6
	printSlice(slice2)
	slice3 := []int{7, 8, 9}
	printSlice(slice3)
}

func nilSlice() {
	slice1 := []int{}
	fmt.Println("slice1 == nil", slice1 == nil)
	var slice2 []int
	fmt.Println("slice2 == nil", slice2 == nil)
	fmt.Println()
}

func testSlice2() {
	array := [5]int{1, 2, 3, 4, 5}
	fmt.Println("[func|testSlice2]array=", array)
	fmt.Println()

	slice1 := array[:]
	fmt.Println("[func|testSlice2]slice1=", slice1)
	fmt.Println()

	slice2 := slice1[:3]
	fmt.Println("[func|testSlice2]slice2=", slice2)
	fmt.Println()

	slice3 := slice2[2:]
	fmt.Println("func|testSlice2]slice3=", slice3)
	fmt.Println()

	slice4 := slice3[1:2]
	slice4[0] = 999
	fmt.Println("[func|testSlice2]slice4=", slice4)
	fmt.Println()
}

func copySlice() {
	slice1 := []int{1, 2, 3, 4}
	slice2 := make([]int, 1, 5)
	copy(slice2, slice1)
	fmt.Println("[func|copySlice]slice1=", slice1)
	fmt.Println("[func|copySlice]slice2=", slice2)
	fmt.Println()
}

func iterationSlice() {
	slice := []int{1, 2, 3, 4, 5}

	for i := 0; i < len(slice); i++ {
		fmt.Println("index: ", i, "value: ", slice[i])
	}
	fmt.Println()

	for index, value := range slice {
		fmt.Println("index: ", index, "value: ", value)
	}
	fmt.Println()
}

func appendSlice() {
	slice := []int{1, 2, 3}
	slice = append(slice, 4)
	fmt.Println("[func|appendSlice]slice=", slice)

	temp := []int{5, 6}
	slice = append(slice, temp...)
	fmt.Println("[func|appendSlice]slice=", slice)

	fmt.Println()
}

func change1(slice []int) {
	slice[0] = 11
	fmt.Println("[func|change1]before append slice=", slice)
	slice = append(slice, 12)
	fmt.Println("[func|change1]after append slice=", slice)
	fmt.Println()
}

func change2(slice *[]int) {
	fmt.Println("[func|change2]before append slice=", slice)
	*slice = append(*slice, 15)
	fmt.Println("[func|change2]after append slice=", slice)
	fmt.Println()
}

func main() {
	testSlice1()

	nilSlice()

	testSlice2()

	copySlice()

	iterationSlice()

	appendSlice()

	slice := []int{1, 2, 3, 4, 5}
	fmt.Println("[func|main]before call change1 slice=", slice)
	change1(slice)
	fmt.Println("[func|main]after call change1 slice=", slice)

	fmt.Println("[func|main]before call change2 slice=", slice)
	change2(&slice)
	fmt.Println("[func|main]after call change2 slice=", slice)
}
